home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
3D GFX
/
3D GFX.iso
/
amiutils
/
i_l
/
irit5
/
illustrt
/
illustrt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-30
|
27KB
|
779 lines
/*****************************************************************************
* Program to create illustrations of wireframe drawings. *
* Usually the output of this program is piped to irit2ps, although it *
* creates a regular IRIT data files with polylines. *
* *
* Written by: Gershon Elber Ver 1.0, June 1993 *
*****************************************************************************/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "program.h"
#include "config.h"
#include "iritgrap.h"
#include "allocate.h"
#include "poly_cln.h"
#include "geomat3d.h"
#include "getarg.h"
#include "ip_cnvrt.h"
#define HEAT_CRV_NUM_PTS 9
#ifdef NO_CONCAT_STR
static char *VersionStr =
"Illustrt Version 5.0, Gershon Elber,\n\
(C) Copyright 1989/90-95 Gershon Elber, Non commercial use only.";
#else
static char *VersionStr =
"Illustrt " VERSION ", Gershon Elber, "
__DATE__ ", " __TIME__ "\n" COPYRIGHT ", Non commercial use only.";
#endif /* NO_CONCAT_STR */
static char *CtrlStr =
#ifdef DOUBLE
"Illustrt I%-#IsoLines!d f%-PolyOpti|SampPerCrv!d!d s%- M%- P%- p%- l%-MaxLnLen!F a%- t%-TrimInter!F o%-OutName!s Z%-InterSameZ!F m%- z%- DFiles!*s";
#else
"Illustrt I%-#IsoLines!d f%-PolyOpti|SampPerCrv!d!d s%- M%- P%- p%- l%-MaxLnLen!f a%- t%-TrimInter!f o%-OutName!s Z%-InterSameZ!f m%- z%- DFiles!*s";
#endif
static char
*GlblOutFileName = "illustrt.dat";
static int
GlblTalkative = FALSE,
GlblSortOutput = FALSE,
GlblPolylineOptiApprox = 0,
GlblDrawSurfaceMesh = FALSE,
GlblDrawSurface = TRUE,
GlblNumOfIsolines = IG_DEFAULT_NUM_OF_ISOLINES,
GlblSamplesPerCurve = IG_DEFAULT_SAMPLES_PER_CURVE;
static RealType
GlblMaxLineLen = DEFAULT_MAX_LINE_LEN;
int GlblAngularDistance = TRUE,
GlblVertexPoints = FALSE,
GlblSplitLongLines = FALSE;
RealType
GlblInterSameZ = INTER_SAME_Z,
GlblTrimIntersect = DEFAULT_TRIM_INTERSECT;
static MatrixType CrntViewMat; /* This is the current view! */
static ConfigStruct SetUp[] =
{
{ "NumOfIsolines", "-I", (VoidPtr) &GlblNumOfIsolines, SU_INTEGER_TYPE },
{ "PolyOpti", "-f", (VoidPtr) &GlblPolylineOptiApprox,SU_INTEGER_TYPE },
{ "SamplesPerCurve","-f", (VoidPtr) &GlblSamplesPerCurve, SU_INTEGER_TYPE },
{ "SortOutput", "-s", (VoidPtr) &GlblSortOutput, SU_BOOLEAN_TYPE },
{ "DrawSurfaceMesh","-M", (VoidPtr) &GlblDrawSurfaceMesh, SU_BOOLEAN_TYPE },
{ "DrawSurface", "-P", (VoidPtr) &GlblDrawSurface, SU_BOOLEAN_TYPE },
{ "VertexPoints", "-p", (VoidPtr) &GlblVertexPoints, SU_BOOLEAN_TYPE },
{ "AngularDist", "-a", (VoidPtr) &GlblAngularDistance, SU_BOOLEAN_TYPE },
{ "MoreVerbose", "-m", (VoidPtr) &GlblTalkative, SU_BOOLEAN_TYPE },
{ "InterSameZ", "-Z", (VoidPtr) &GlblInterSameZ, SU_REAL_TYPE }
};
#define NUM_SET_UP (sizeof(SetUp) / sizeof(ConfigStruct))
static void DumpData(char *FileName,
IPObjectStruct *NoProcessObjs,
IPObjectStruct *PObjects);
static IPObjectStruct *ProcessSpeedWave(IPObjectStruct *PObj,
char *SpeedWaveAttrs);
static IPPolygonStruct *GenSpeedWave(RealType Coords[3],
RealType GenRand,
RealType Dir[3],
RealType Len,
RealType Dist,
RealType LenRand,
RealType DistRand);
static IPObjectStruct *ProcessHeatWave(IPObjectStruct *PObj,
char *HeatWaveAttrs);
static CagdCrvStruct *GenHeatWave(RealType Coords[3],
RealType GenRand,
RealType Len,
RealType Dist,
RealType LenRand,
RealType DistRand);
/*****************************************************************************
* DESCRIPTION: M
* Main module of illustrt - Read command line and do what is needed... M
* *
* PARAMETERS: M
* argc, argv: Command line. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* main M
*****************************************************************************/
void main(int argc, char **argv)
{
int Error,
NumOfIsolinesFlag = FALSE,
CrvOptiPolylinesFlag = FALSE,
TrimInterFlag = FALSE,
OutFileFlag = FALSE,
InterSameZFlag = FALSE,
VerFlag = FALSE,
NumFiles = 0;
char
**FileNames = NULL;
IPObjectStruct *PObjects, *NoProcessObjs, *PObj,
*PObjWaves = NULL;
Config("illustrt", SetUp, NUM_SET_UP); /* Read config. file if exists. */
if ((Error = GAGetArgs(argc, argv, CtrlStr,
&NumOfIsolinesFlag, &GlblNumOfIsolines,
&CrvOptiPolylinesFlag, &GlblPolylineOptiApprox,
&GlblSamplesPerCurve,
&GlblSortOutput, &GlblDrawSurfaceMesh,
&GlblDrawSurface, &GlblVertexPoints,
&GlblSplitLongLines, &GlblMaxLineLen,
&GlblAngularDistance,
&TrimInterFlag, &GlblTrimIntersect,
&OutFileFlag, &GlblOutFileName,
&InterSameZFlag, &GlblInterSameZ, &GlblTalkative,
&VerFlag, &NumFiles, &FileNames)) != 0) {
GAPrintErrMsg(Error);
GAPrintHowTo(CtrlStr);
IllustrateExit(1);
}
if (VerFlag) {
fprintf(stderr, "\n%s\n\n", VersionStr);
GAPrintHowTo(CtrlStr);
ConfigPrint(SetUp, NUM_SET_UP);
IllustrateExit(0);
}
if (!NumFiles) {
fprintf(stderr, "No data file names where given, exit.\n");
GAPrintHowTo(CtrlStr);
IllustrateExit(1);
}
/* Get the data files: */
if ((PObjects = IritPrsrGetDataFiles(FileNames, NumFiles, TRUE, FALSE)) ==
NULL)
IllustrateExit(0);
if (IritPrsrWasPrspMat)
MatMultTwo4by4(CrntViewMat, IritPrsrViewMat, IritPrsrPrspMat);
else
GEN_COPY(CrntViewMat, IritPrsrViewMat, sizeof(MatrixType));
/* Scan the objects for wave supported attributes. */
for (PObj = PObjects; PObj != NULL; PObj = PObj -> Pnext) {
IPObjectStruct *PObjWave;
char *p;
if ((p = AttrGetObjectStrAttrib(PObj, "speedwave")) != NULL &&
(PObjWave = ProcessSpeedWave(PObj, p)) != NULL) {
PObjWave -> Pnext = PObjWaves;
PObjWaves = PObjWave;
}
if ((p = AttrGetObjectStrAttrib(PObj, "heatwave")) != NULL &&
(PObjWave = ProcessHeatWave(PObj, p)) != NULL) {
PObjWave -> Pnext = PObjWaves;
PObjWaves = PObjWave;
}
}
PObj = GMTransformObjectList(PObjects, CrntViewMat);
IPFreeObjectList(PObjects);
PObjects = PObj;
if (PObjWaves != NULL) {
PObj = GMTransformObjectList(PObjWaves, CrntViewMat);
IPFreeObjectList(PObjWaves);
PObjWaves = PObj;
}
for (PObj = PObjects, PObjects = NoProcessObjs = NULL; PObj != NULL; ) {
IPObjectStruct
*PObjNext = PObj -> Pnext;
if (AttrGetObjectStrAttrib(PObj, "IllustrtNoProcess") != NULL) {
PObj -> Pnext = NoProcessObjs;
NoProcessObjs = PObj;
}
else {
PObj -> Pnext = PObjects;
PObjects = PObj;
}
PObj = PObjNext;
}
if (GlblVertexPoints) {
/* Add vertices of each polyline as points into data set. */
for (PObj = PObjects; PObj != NULL;) {
if (IP_IS_POLY_OBJ(PObj)) {
IPObjectStruct
*PtList = CopyObject(NULL, PObj, TRUE);
IP_SET_POINTLIST_OBJ(PtList);
RemoveInternalVertices(PtList);
PObj -> Pnext = PtList;
PObj = PtList -> Pnext;
}
else
PObj = PObj -> Pnext;
}
}
ProcessIntersections(PObjects);
if (GlblSplitLongLines)
SplitLongLines(PObjects, GlblMaxLineLen);
if (GlblSortOutput)
SortOutput(&PObjects);
/* Append the objects created to represent waves. */
PObj = IritPrsrGetLastObj(PObjects);
PObj -> Pnext = PObjWaves;
DumpData(OutFileFlag ? GlblOutFileName : NULL, NoProcessObjs, PObjects);
IllustrateExit(0);
}
/*****************************************************************************
* DESCRIPTION: M
* Routine to convert all surfaces/curves into polylines as follows: M
* Curve is converted to a single polyline with SamplesPerCurve samples. M
* Surface is converted into GlblNumOfIsolines curves in each axes, each M
* handled as Curve above. The original curves and surfaces are then deleted. M
* This function is a call back function of the irit parser. M
* *
* PARAMETERS: M
* FreeForms: Crvs/Srfs/Trimmed Srfs/Trivariates read from a file by the M
* irit parser. M
* *
* RETURN VALUE: M
* IPObjectStruct *: Processed freeform geometry. This function simply M
* returns what it gots. M
* *
* KEYWORDS: M
* IritPrsrProcessFreeForm, conversion M
*****************************************************************************/
IPObjectStruct *IritPrsrProcessFreeForm(IritPrsrFreeFormStruct *FreeForms)
{
CagdCrvStruct *Crv, *Crvs;
CagdSrfStruct *Srf, *Srfs;
IPObjectStruct *PObj,
*CrvObjs = FreeForms -> CrvObjs,
*SrfObjs = FreeForms -> SrfObjs;
IPPolygonStruct *PPolygon, *PPolygonTemp;
if (CrvObjs == NULL && SrfObjs == NULL)
return NULL;
/* Make sure requested format is something reasonable. */
if (GlblNumOfIsolines < 2) {
GlblNumOfIsolines = 2;
fprintf(stderr, "NumOfIsolines is less than 2, 2 picked instead.\n");
}
if (GlblSamplesPerCurve < 2) {
GlblSamplesPerCurve = 2;
fprintf(stderr,
"SamplesPerCurve is less than 2, 2 picked instead.\n");
}
if (CrvObjs) {
for (PObj = CrvObjs; PObj != NULL; PObj = PObj -> Pnext) {
if (GlblTalkative)
fprintf(stderr, "Processing curve object \"%s\"\n",
PObj -> Name);
Crvs = PObj -> U.Crvs;
PObj -> U.Pl = NULL;
PObj -> ObjType = IP_OBJ_POLY;
IP_SET_POLYLINE_OBJ(PObj);
for (Crv = Crvs; Crv != NULL; Crv = Crv -> Pnext) {
PPolygon = PPolygonTemp =
IritCurve2Polylines(Crv, GlblSamplesPerCurve,
GlblPolylineOptiApprox);
if (PPolygon != NULL) {
while (PPolygonTemp -> Pnext)
PPolygonTemp = PPolygonTemp -> Pnext;
PPolygonTemp -> Pnext = PObj -> U.Pl;
PObj -> U.Pl = PPolygon;
}
}
CagdCrvFreeList(Crvs);
}
}
if (SrfObjs) {
int NumOfIso[2];
NumOfIso[0] = -GlblNumOfIsolines;
NumOfIso[1] = -GlblNumOfIsolines;
for (PObj = SrfObjs; PObj != NULL; PObj = PObj -> Pnext) {
if (GlblTalkative)
fprintf(stderr, "Processing surface object \"%s\"\n",
PObj -> Name);
Srfs = PObj -> U.Srfs;
PObj -> U.Pl = NULL;
PObj -> ObjType = IP_OBJ_POLY;
IP_SET_POLYLINE_OBJ(PObj);
for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
PPolygon = PPolygonTemp =
IritSurface2Polylines(Srf, NumOfIso,
GlblSamplesPerCurve,
GlblPolylineOptiApprox);
if (PPolygon != NULL) {
while (PPolygonTemp -> Pnext)
PPolygonTemp = PPolygonTemp -> Pnext;
PPolygonTemp -> Pnext = PObj -> U.Pl;
PObj -> U.Pl = PPolygon;
}
}
CagdSrfFreeList(Srfs);
}
}
if (SrfObjs == NULL)
return CrvObjs;
else if (CrvObjs == NULL)
return SrfObjs;
else {
for (PObj = SrfObjs; PObj -> Pnext != NULL; PObj = PObj -> Pnext);
PObj -> Pnext = CrvObjs;
return SrfObjs;
}
}
/*****************************************************************************
* DESCRIPTION: *
* Dumps the data out into FileName (stdout in NULL). *
* *
* PARAMETERS: *
* FileName: Where output should go to. *
* NoProcessObjs: List of object that are piped through from input stream *
* unprocessed. *
* PObjects: List of processed object to dump out. *
* *
* RETURN VALUE: *
* void *
*****************************************************************************/
static void DumpData(char *FileName,
IPObjectStruct *NoProcessObjs,
IPObjectStruct *PObjects)
{
FILE *f;
if (FileName != NULL) {
if ((f = fopen(FileName, "w")) == NULL) {
fprintf(stderr, "Failed to open \"%s\".\n", FileName);
IllustrateExit(2);
}
}
else
f = stdout;
fprintf(f, "\tIrit Solid Modeller Data File (ILLUSTRT), %s\n\n",
IritRealTimeDate());
while (PObjects) {
/* Dump only polys with at least two vertices and points/vectors. */
if (IP_IS_POLY_OBJ(PObjects)) {
if (IP_IS_POLYLINE_OBJ(PObjects))
CleanUpPolylineList(&PObjects -> U.Pl);
if (PObjects -> U.Pl != NULL)
IritPrsrPutObjectToFile(f, PObjects);
}
else if (IP_IS_POINT_OBJ(PObjects) ||
IP_IS_VEC_OBJ(PObjects) ||
IP_IS_CRV_OBJ(PObjects)) {
IritPrsrPutObjectToFile(f, PObjects);
}
PObjects = PObjects -> Pnext;
}
while (NoProcessObjs) {
IritPrsrPutObjectToFile(f, NoProcessObjs);
NoProcessObjs = NoProcessObjs -> Pnext;
}
fclose(f);
}
/*****************************************************************************
* DESCRIPTION: *
* Creates an object representing speed wave from object PObj. SpeedWaveAttr *
* Holds the attributes of the speed wave in the following format: *
* "GenRand,DirX,DirY,DirZ,Len,Dist,LenRand,DistRand,Width" with *
* See GenSpeedWave below. *
* *
* PARAMETERS: *
* PObj: Object for which a speed wave it to be generated. *
* SpeedWaveAttrs: String describing a speed wave. *
* *
* RETURN VALUE: *
* IPObjectStruct *: Object representing a speed wave. *
*****************************************************************************/
static IPObjectStruct *ProcessSpeedWave(IPObjectStruct *PObj,
char *SpeedWaveAttrs)
{
int i, NumPoints;
char StrLineWidth[LINE_LEN];
RealType **Points, GenRand, Dir[3], Len, Dist, LenRand, DistRand, Width;
CagdSrfStruct
*Srf = NULL;
CagdCrvStruct
*Crv = NULL;
IPObjectStruct *PObjTmp, *PObjWave;
IPPolygonStruct *P, *PWave;
#ifdef DOUBLE
if (sscanf(SpeedWaveAttrs, "%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf",
#else
if (sscanf(SpeedWaveAttrs, "%f,%f,%f,%f,%f,%f,%f,%f,%f",
#endif /* DOUBLE */
&GenRand, &Dir[0], &Dir[1], &Dir[2], &Len,
&Dist, &LenRand, &DistRand, &Width) != 9) {
fprintf(stderr, "Wrong parameters of speed wave. Ignored.\n");
return NULL;
}
PObjWave = IPAllocObject("SpeedWave", IP_OBJ_POLY, NULL);
sprintf(StrLineWidth, "%f", Width);
AttrSetObjectStrAttrib(PObjWave, "width", StrLineWidth);
IP_SET_POLYLINE_OBJ(PObjWave);
switch (PObj -> ObjType) {
case IP_OBJ_LIST_OBJ:
for (i = 0; (PObjTmp = ListObjectGet(PObj, i)) != NULL; i++)
ProcessSpeedWave(PObjTmp, SpeedWaveAttrs);
break;
case IP_OBJ_POLY:
for (P = PObj -> U.Pl; P != NULL; P = P -> Pnext) {
IPVertexStruct
*V = P -> PVertex;
do {
if ((PWave = GenSpeedWave(V -> Coord, GenRand, Dir, Len,
Dist, LenRand, DistRand)) != NULL) {
PWave -> Pnext = PObjWave -> U.Pl;
PObjWave -> U.Pl = PWave;
}
V = V -> Pnext;
}
while (V != NULL && V != P -> PVertex);
}
break;
case IP_OBJ_SURFACE:
case IP_OBJ_CURVE:
if (PObj -> ObjType == IP_OBJ_SURFACE) {
Srf = CagdCoerceSrfTo(PObj -> U.Srfs, CAGD_PT_E3_TYPE);
Points = Srf -> Points;
NumPoints = Srf -> ULength * Srf -> VLength;
}
else {
Crv = CagdCoerceCrvTo(PObj -> U.Crvs, CAGD_PT_E3_TYPE);
Points = Crv -> Points;
NumPoints = Crv -> Length;
}
for (i = 0; i < NumPoints; i++) {
int j;
RealType Coords[3];
for (j = 0; j < 3; j++)
Coords[j] = Points[j + 1][i];
if ((PWave = GenSpeedWave(Coords, GenRand, Dir, Len,
Dist, LenRand, DistRand)) != NULL) {
PWave -> Pnext = PObjWave -> U.Pl;
PObjWave -> U.Pl = PWave;
}
}
if (PObj -> ObjType == IP_OBJ_SURFACE)
CagdSrfFree(Srf);
else
CagdCrvFree(Crv);
break;
default:
break;
}
if (PObjWave -> U.Pl != NULL)
return PObjWave;
else {
IPFreeObject(PObjWave);
return NULL;
}
}
/*****************************************************************************
* DESCRIPTION: *
* Randomly generates a single speed wave instance. *
* *
* PARAMETERS: *
* Coords: Location for which the wave is to be generated. *
* GenRand: Probability of generating the wave. *
* Dir: Direction of wave. *
* Len, Dist: Length of the wave and distance from object. *
* LenRand, DistRand: Pertubation amount Len and Dist. *
* *
* RETURN VALUE: *
* IPPolygonStruct *: An object representing one speed wave object *
* in probability GenRand, NULL otherwise. *
*****************************************************************************/
static IPPolygonStruct *GenSpeedWave(RealType Coords[3],
RealType GenRand,
RealType Dir[3],
RealType Len,
RealType Dist,
RealType LenRand,
RealType DistRand)
{
VectorType DirCopy;
IPVertexStruct *V1, *V2;
IPPolygonStruct *P;
/* Test if probability is in favor. */
if (IritRandom(0.0, 1.0) > GenRand)
return NULL;
V2 = IPAllocVertex(0, 0, NULL, NULL);
V1 = IPAllocVertex(0, 0, NULL, V2);
P = IPAllocPolygon(0, 0, V1, NULL);
PT_COPY(DirCopy, Dir);
PT_NORMALIZE(DirCopy);
Dist += DistRand * IritRandom(-1.0, 1.0);
PT_SCALE(DirCopy, Dist);
PT_COPY(V1 -> Coord, Coords);
PT_ADD(V1 -> Coord, V1 -> Coord, DirCopy);
PT_COPY(DirCopy, Dir);
PT_NORMALIZE(DirCopy);
Len += LenRand * IritRandom(-1.0, 1.0);
PT_SCALE(DirCopy, Len);
PT_COPY(V2 -> Coord, V1 -> Coord);
PT_ADD(V2 -> Coord, V2 -> Coord, DirCopy);
return P;
}
/*****************************************************************************
* DESCRIPTION: *
* Creates an object representing heat wave from object PObj. HeatWaveAttr *
* Holds the attributes of the heat wave in the following format: *
* "GenRand,Len,Dist,LenRand,DistRand,Width" with *
* See GenHeatWave below. *
* *
* PARAMETERS: *
* PObj: Object for which a heat wave it to be generated. *
* SpeedWaveAttrs: String describing a heat wave. *
* *
* RETURN VALUE: *
* IPObjectStruct *: Object representing a heat wave. *
*****************************************************************************/
static IPObjectStruct *ProcessHeatWave(IPObjectStruct *PObj,
char *HeatWaveAttrs)
{
int i, NumPoints;
RealType **Points, GenRand, Len, Dist, LenRand, DistRand, Width;
CagdSrfStruct
*Srf = NULL;
CagdCrvStruct *PWave,
*Crv = NULL;
IPObjectStruct *PObjTmp, *PObjWave;
IPPolygonStruct *P;
#ifdef DOUBLE
if (sscanf(HeatWaveAttrs, "%lf,%lf,%lf,%lf,%lf,%lf",
#else
if (sscanf(HeatWaveAttrs, "%f,%f,%f,%f,%f,%f",
#endif /* DOUBLE */
&GenRand, &Len, &Dist, &LenRand, &DistRand, &Width) != 6) {
fprintf(stderr, "Wrong parameters of heat wave. Ignored.\n");
return NULL;
}
PObjWave = IPAllocObject("HeatWave", IP_OBJ_CURVE, NULL);
AttrSetObjectRealAttrib(PObjWave, "width", Width);
switch (PObj -> ObjType) {
case IP_OBJ_LIST_OBJ:
for (i = 0; (PObjTmp = ListObjectGet(PObj, i)) != NULL; i++)
ProcessHeatWave(PObjTmp, HeatWaveAttrs);
break;
case IP_OBJ_POLY:
for (P = PObj -> U.Pl; P != NULL; P = P -> Pnext) {
IPVertexStruct
*V = P -> PVertex;
do {
if ((PWave = GenHeatWave(V -> Coord, GenRand, Len,
Dist, LenRand, DistRand)) != NULL) {
PWave -> Pnext = PObjWave -> U.Crvs;
PObjWave -> U.Crvs = PWave;
}
V = V -> Pnext;
}
while (V != NULL && V != P -> PVertex);
}
break;
case IP_OBJ_SURFACE:
case IP_OBJ_CURVE:
if (PObj -> ObjType == IP_OBJ_SURFACE) {
Srf = CagdCoerceSrfTo(PObj -> U.Srfs, CAGD_PT_E3_TYPE);
Points = Srf -> Points;
NumPoints = Srf -> ULength * Srf -> VLength;
}
else {
Crv = CagdCoerceCrvTo(PObj -> U.Crvs, CAGD_PT_E3_TYPE);
Points = Crv -> Points;
NumPoints = Crv -> Length;
}
for (i = 0; i < NumPoints; i++) {
int j;
RealType Coords[3];
for (j = 0; j < 3; j++)
Coords[j] = Points[j + 1][i];
if ((PWave = GenHeatWave(Coords, GenRand, Len,
Dist, LenRand, DistRand)) != NULL) {
PWave -> Pnext = PObjWave -> U.Crvs;
PObjWave -> U.Crvs = PWave;
}
}
if (PObj -> ObjType == IP_OBJ_SURFACE)
CagdSrfFree(Srf);
else
CagdCrvFree(Crv);
break;
default:
break;
}
if (PObjWave -> U.Pl != NULL)
return PObjWave;
else {
IPFreeObject(PObjWave);
return NULL;
}
}
/*****************************************************************************
* DESCRIPTION: *
* Randomly generates a single heat wave instance. *
* *
* PARAMETERS: *
* Coords: Location for which the wave is to be generated. *
* GenRand: Probability of generating the wave. *
* Len, Dist: Length of the wave and distance from object. *
* LenRand, DistRand: Pertubation amount Len and Dist. *
* *
* RETURN VALUE: *
* CagdCrvStruct *: An object representing one heat wave object *
* in probability GenRand, NULL otherwise. *
*****************************************************************************/
static CagdCrvStruct *GenHeatWave(RealType Coords[3],
RealType GenRand,
RealType Len,
RealType Dist,
RealType LenRand,
RealType DistRand)
{
static VectorType
HeatCtlPts[HEAT_CRV_NUM_PTS] =
{
{ 0.0, 0.0, 0.0 },
{ 0.1, 0.0, 0.25 },
{ 0.0, 0.1, 0.3 },
{ 0.0, 0.0, 0.2 },
{ 0.1, 0.0, 0.35 },
{ 0.0, 0.0, 0.5 },
{ 0.0, 0.0, 0.35 },
{ 0.1, 0.1, 0.5 },
{ 0.1, 0.0, 0.6 },
};
int i, j;
CagdCrvStruct *Crv;
/* Test if probability is in favor. */
if (IritRandom(0.0, 1.0) > GenRand)
return NULL;
Len += LenRand * IritRandom(-1.0, 1.0);
Dist += DistRand * IritRandom(-1.0, 1.0);
Crv = BspCrvNew(HEAT_CRV_NUM_PTS, 3, CAGD_PT_E3_TYPE);
BspKnotUniformOpen(HEAT_CRV_NUM_PTS, 3, Crv -> KnotVector);
for (i = 0; i < HEAT_CRV_NUM_PTS; i++)
for (j = 0; j < 3; j++)
Crv -> Points[j + 1][i] = Coords[j] + (j == 2 ? Dist : 0.0) +
HeatCtlPts[i][j] * Len;
return Crv;
}
/*****************************************************************************
* DESCRIPTION: M
* Illustrt Exit routine. M
* *
* PARAMETERS: M
* ExitCode: To notify O.S. with result of program. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* IllustrateExit M
*****************************************************************************/
void IllustrateExit(int ExitCode)
{
exit(ExitCode);
}
#ifdef DEBUG
/*****************************************************************************
* DESCRIPTION: *
* Dummy function to link at debugging time. *
* *
* PARAMETERS: *
* *
* RETURN VALUE: *
* void *
* *
* KEYWORDS: *
*****************************************************************************/
void DummyLinkCagdDebug(void)
{
IritPrsrDbg();
}
#endif /* DEBUG */